/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *
 * Copyright @2008 the original author or authors.
 */
package com.bluestone;

import java.awt.Robot;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;

import bsh.Interpreter;

import com.bluestone.context.ActionContext;
import com.bluestone.context.IContext;
import com.bluestone.scripts.ActionScript;
import com.bluestone.scripts.Attributes;
import com.bluestone.scripts.Property;
import com.bluestone.util.Util;

/**
 * An action is an object having a graphical behavior on the screen. Examples of
 * actions are the ClickAction,DelayAction and MoveAction. The Action class is
 * the abstract superclass of graphical behavior.
 * 
 * @author <a href="mailto:bluestone.daniel.q@gmail.com">daniel.q</a>
 * 
 */
public abstract class BaseAction implements IAction {
	
	private String id = ""+ System.currentTimeMillis();
	
	protected ActionScript action = null;
	
	protected ActionContext actionContext = null;

	protected Robot robot = Util.getRobot();

	public BaseAction(ActionScript action) {
		this.action = action;
	}


	public String getPara(String key) {
		if (action.getParas().containsKey(key)) {
			return (String) action.getParas().get(key);
		} else {
			Util.warn("The action does not contain the expand attribute of "
					+ key);
		}
		return null;
	}
    public ActionScript getAction(){
    	return this.action;
    }

	public String getType() {
		return action.getType();
	}

	public void setType(String type) {
		action.setType(type);
	}

	public boolean isValid(IContext context) {

		String cond = action.getPara("cond");
		if (cond != null && cond.length() > 0) {
			List<Property> properties = ((ActionContext)context).getProjectContext().getProject().getProperties();
			if(properties==null){
				//TODO ....
				return true;
			}
			Interpreter interpreter = new Interpreter();
			for (Property property : properties) {
				if (ResourceBundle.class.isInstance(property.getObject())) {
					ResourceBundle rb = (ResourceBundle) property.getObject();
					java.util.Enumeration en = rb.getKeys();
					while (en.hasMoreElements()) {
						String key = (String) en.nextElement();
						String value = rb.getString(key);
						try {
							interpreter.set(key, Boolean.parseBoolean(value));
						} catch (Exception me) {
							Util.getLogger().error("set interpreter:" + key + "=" + value + me);
						}
					}

				}
			}
			
			//add dynamic proper
			Iterator iterator = Util.getDynamicPropMap().keySet().iterator();
			while(iterator.hasNext()){
				String key = (String)iterator.next();
				String value = (String)Util.getDynamicPropMap().get(key);
				try {
					interpreter.set(key, Boolean.parseBoolean(value));
				} catch (Exception me) {
					Util.getLogger().error("set interpreter:" + key + "=" + value + me);
				}
			}
			
			try {
				boolean result = ((Boolean) interpreter.eval(cond))
				.booleanValue();
				Util.info("condition:" + cond+"-->"+result);
				return result;
			} catch (Exception me) {
				Util.getLogger().error("BaseAction isValid "+ cond + me);
				return false;
			}

		}
		return true;
	}

	/**
	 * Abstract implements of the IAction.execute().
	 * 
	 * @return false if the operator of the action is null.
	 */
	public boolean execute(IContext context) {
		actionContext = (ActionContext)context;
		if (robot == null) {
			return false;
		}
		return true;
	}

	public String toString() {
		String str = "action:";
		str = str + action.getType() + ",";
		str = str + action.getPara("target") + ",";
		String value = action.getPara("value");
		if (value != null && value.startsWith("@")) {
			str = str + Util.getString(value);
		} else {
			str = str + value;
		}

		return (str);
	}

	/**
	 * 
	 * @return robot that defines the action operator
	 */
	public java.awt.Robot getRobot() {
		return robot;
	}

	public void setRobot(java.awt.Robot robot) {
		this.robot = robot;
	}

	public Object getParent() {
		return action.getParent();
	}

	public void setParent(Object parent) {
		action.setParent(parent);
	}

	public String getName() {
		return action.getName();
	}

}
